# Plain go version
go version
! stdout go1\.999

# Default should be auto
env GOTOOLCHAIN=
go env GOTOOLCHAIN
stdout auto
go env
stdout GOTOOLCHAIN=.?auto.?

# GOTOOLCHAIN from network, does not exist
env GOTOOLCHAIN=go1.9999x
! go version
stderr 'go: download go1.9999x for .*: toolchain not available'

[short] skip

env GOTOOLCHAIN=
mkdir $WORK/bin
[!GOOS:plan9] env PATH=$WORK/bin${:}$PATH
[GOOS:plan9] env path=$WORK/bin${:}$path
go build -o $WORK/bin/ ./go1.999testpath.go  # adds .exe extension implicitly on Windows
cp $WORK/bin/go1.999testpath$GOEXE $WORK/bin/custom-go1.999.0$GOEXE
cp $WORK/bin/go1.999testpath$GOEXE $WORK/bin/go1.999.0-custom$GOEXE

# GOTOOLCHAIN from PATH
env GOTOOLCHAIN=go1.999testpath
go version
stdout 'go1.999testpath here!'

# GOTOOLCHAIN from PATH, with forced subprocess
env GOTOOLCHAIN=go1.999testpath
env GODEBUG=gotoolchainexec=0
go version
stdout 'go1.999testpath here!'
env GODEBUG=

# GOTOOLCHAIN from network
[!exec:/bin/sh] stop 'the fake proxy serves shell scripts instead of binaries'
env GOTOOLCHAIN=go1.999testmod
go version
stderr 'go: downloading go1.999testmod \(.*/.*\)'

# GOTOOLCHAIN=auto
env GOTOOLCHAIN=auto
env TESTGO_VERSION=go1.100

# toolchain line in go.mod
cp go119toolchain1999 go.mod
go version
stdout go1.999

# custom toolchain line in go.mod
env TESTGO_VERSION=go1.999
go version
stdout testpath # go1.999 < go1.999testpath

env TESTGO_VERSION=go1.999.0
go version
! stdout testpath # go1.999testpath < go1.999.0

cp go119customtoolchain1999 go.mod
go version
stdout go1.999testpath # custom-go1.999.0 >= go1.999.0

cp go119customtoolchain1999b go.mod
go version
stdout go1.999testpath # go1.999.0-custom >= go1.999.0

env TESTGO_VERSION=go1.100

# toolchain local in go.mod
cp go1999toolchainlocal go.mod
! go build
stderr '^go: go.mod requires go 1.999 \(running go 1.100; go.mod sets go 1.999, toolchain local\)$'

# toolchain local in go.work
cp empty go.mod
cp go1999toolchainlocal go.work
! go build
stderr '^go: go.work requires go 1.999 \(running go 1.100; go.work sets go 1.999, toolchain local\)$'
rm go.work

# toolchain line in go.work
cp empty go.mod
cp go119toolchain1999 go.work
go version
stdout go1.999
rm go.work

# go version in go.mod
cp go1999 go.mod
go version
stdout go1.999

# go version in go.work
cp empty go.mod
cp go1999 go.work
go version
stdout go1.999
rm go.work

# GOTOOLCHAIN=auto falls back to local toolchain if newer than go or toolchain line
env TESTGO_VERSION=go1.1000

# toolchain line in go.mod
cp go119toolchain1999 go.mod
go version
stdout go1.1000

# toolchain line in go.work
cp empty go.mod
cp go119toolchain1999 go.work
go version
stdout go1.1000
rm go.work

# go version in go.mod
cp go1999 go.mod
go version
stdout go1.1000

# go version in go.work
cp empty go.mod
cp go1999 go.work
go version
stdout go1.1000
rm go.work

# GOTOOLCHAIN=auto uses different toolchain when instructed and newer
env TESTGO_VERSION=go1.100

# toolchain line in go.mod
cp go119toolchain1999 go.mod
go version
stdout go1.999

# toolchain line in go.work
cp empty go.mod
cp go119toolchain1999 go.work
go version
stdout go1.999
rm go.work

# go version in go.mod
cp go1999 go.mod
go version
stdout go1.999

# go version in go.work
cp empty go.mod
cp go1999 go.work
go version
stdout go1.999
rm go.work

# go1.999 should handle go1.998 without a download
env TESTGO_VERSION=go1.999
cp go1998 go.mod
go version
! stdout go1.998 # local toolchain instead

# go1.998 should handle go1.998 without a download too
env TESTGO_VERSION=go1.999
go version
stdout go1.999 # local toolchain instead

# go1.998+foo should handle go1.998 without a download too
env TESTGO_VERSION=go1.998+foo
go version
stdout 'go1.998\+foo' # local toolchain instead

# go1.998-foo should handle go1.998 without a download too
env TESTGO_VERSION=go1.998-foo
go version
stdout go1.998-foo # local toolchain instead

# 'go1.998 foo' should handle go1.998 without a download too
env TESTGO_VERSION='go1.998 foo'
go version
stdout 'go1.998 foo' # local toolchain instead

# go1.997-foo should download go1.998
env TESTGO_VERSION=go1.997-foo
! go version
stderr go1.998

# GOTOOLCHAIN=go1.1000+auto falls back to go1.1000 if newer than go line
env TESTGO_VERSION=go1.1
env GOTOOLCHAIN=go1.1000+auto

# toolchain line in go.mod
cp go119toolchain1999 go.mod
! go version
stderr go1.1000

# toolchain line in go.work
cp empty go.mod
cp go119toolchain1999 go.work
! go version
stderr go1.1000
rm go.work

# go version in go.mod
cp go1999 go.mod
! go version
stderr go1.1000

# go version in go.work
cp empty go.mod
cp go1999 go.work
! go version
stderr go1.1000
rm go.work

# GOTOOLCHAIN=path refuses to download
env GOTOOLCHAIN=path
env TESTGO_VERSION=go1.19

cp go1999 go.mod
go version
stdout go1.999

cp go1999mod go.mod
! go version
stderr '^go: cannot find "go1.999mod" in PATH$'

# go install m@v should use go version in m@v's go.mod
env GOTOOLCHAIN=path
env TESTGO_VERSION=go1.19
cp go1999 go.mod
! go install rsc.io/fortune/nonexist@v0.0.1
stderr '^go: cannot find "go1.21rc999" in PATH$'

# go install m@v should handle queries
! go install rsc.io/fortune/nonexist@v0.0
stderr '^go: cannot find "go1.21rc999" in PATH$'

# go run m@v should use go version in m@v's go.mod
env GOTOOLCHAIN=path
env TESTGO_VERSION=go1.19
cp go1999 go.mod
! go run -unknownflag=here rsc.io/fortune/nonexist@v0.0.1 args here
stderr '^go: cannot find "go1.21rc999" in PATH$'
go run -unknownflag here rsc.io/fortune/nonexist@v0.0.1
stdout 'go1.999testpath here!'

# go run m@v should handle known flags correctly
! go run -gcflags foo rsc.io/fortune/nonexist@v0.0.1 args here
stderr '^go: cannot find "go1.21rc999" in PATH$'
! go run -x rsc.io/fortune/nonexist@v0.0.1 args here
stderr '^go: cannot find "go1.21rc999" in PATH$'

# go run m@v should handle queries
! go run rsc.io/fortune/nonexist@v0
stderr '^go: cannot find "go1.21rc999" in PATH$'

# go install m@v should work if not upgrading
go install rsc.io/fortune/nonexist@v1
stderr '^go: downloading rsc.io/fortune v1.0.0$'
stdout '^go1.999testpath here!'

-- empty --

-- go1999 --
go 1.999testpath

-- go1998 --
go 1.998

-- go1999mod --
go 1.999mod

-- go119 ---
go 1.19

-- go119toolchain1999 --
go 1.19
toolchain go1.999testpath

-- go119customtoolchain1999 --
go 1.19
toolchain custom-go1.999.0

-- go119customtoolchain1999b --
go 1.19
toolchain go1.999.0-custom

-- go1999toolchainlocal --
go 1.999
toolchain local

-- go1.999testpath.go --
package main

import "os"

func main() {
	os.Stdout.WriteString("go1.999testpath here!\n")
}
